#pragma once
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <stdlib.h>

#define Calf "-" // 时间分割分隔符
using namespace std;
typedef std::vector<std::vector<std::pair<std::string, std::string>>> Data;
typedef int End_Time;
typedef int workerId;
int timeToMinutes(string timeStr)
{
    // 将时间字符串按照 "-" 分隔成时和分两个部分
    int hour, minute;
    if (timeStr.size() == 4)
    {
        hour = stoi(timeStr.substr(0, 1));
        minute = stoi(timeStr.substr(2, 2));
    }
    else
    {
        hour = stoi(timeStr.substr(0, 2));
        minute = stoi(timeStr.substr(3, 2));
    }

    // 将时间转换成分钟数
    int minutes = (hour - 7) * 60 + minute;
    if (minutes < 0 || minutes > 10 * 60)
    {
        // 如果时间不在 7:00 - 17:00 范围内，返回一个错误值
        return -1;
    }
    return minutes;
}

int getValue(const std::string &type, const std::string &fee)
{
    int value;
    if (strcmp(type.c_str(), "水管维修") == 0)
    {
        value += 8;
    }
    else if (strcmp(type.c_str(), "电路维修") == 0)
    {
        value += 5;
    }
    else if (strcmp(type.c_str(), "电梯维修") == 0)
    {
        value += 10;
    }
    else if (strcmp(type.c_str(), "消防维修") == 0)
    {
        value += 10;
    }
    else if (strcmp(type.c_str(), "家具维修") == 0)
    {
        value += 6;
    }
    value += atoi(fee.c_str()) / 20;
    return value;
}

int getWaste(const string &type)
{
    if (strcmp(type.c_str(), "水管维修") == 0)
    {
        return 30;
    }
    else if (strcmp(type.c_str(), "电路维修") == 0)
    {
        return 40;
    }
    else if (strcmp(type.c_str(), "电梯维修") == 0)
    {
        return 60;
    }
    else if (strcmp(type.c_str(), "消防维修") == 0)
    {
        return 50;
    }
    else if (strcmp(type.c_str(), "家具维修") == 0)
    {
        return 50;
    }
}
// 任务调度类
class Handler
{
private:
    struct Task
    {
        Task(int i, int s, int d, double r)
            : id(i), start(s),duration(d), rate(r)
        {
        }
        int id;       // 任务编号
        int start;    // 任务开始时间
        int end;      // 任务结束时间
        int duration; // 完成任务所需时间
        double rate;    // 任务权值
    };
    vector<Task> tasks;                       // 任务集
    vector<pair<int, workerId>> task_list;         // 任务列表
    vector<pair<workerId, End_Time>> workers; // 工人
public:
    void AddTask(const Data &input)
    {
        for (int i = 0; i < input.size(); i++)
        {
            string time = input[i][4].second;
            // vector<char *> res;
            // char *str = NULL;
            // for (str = strtok(const_cast<char *>(time.c_str()), Calf); str != NULL; str = strtok(NULL, Calf))
            // {
            //     res.push_back(str);
            // }
            // for(auto &s:res)
            // {
            //     LOG(DEBUG,s);
            // }
            int begin_time = timeToMinutes(time);
            //int begin_time = timeToMinutes(res[0]);
            // int end_time = timeToMinutes(res[1]);
            double finish_time = getWaste(input[i][2].second);
            double value = getValue(input[i][2].second, input[i][3].second);
            double rate =value/finish_time;
            tasks.push_back(Task(i, begin_time, finish_time, rate));
        }
    }
    // 按照任务开始时间从小到大排序
    static bool cmp(const Task &a, const Task &b)
    {
        return a.start < b.start;
    }

    // 按工人任务结束时间从小到大排序
    static bool cmp_worker(const pair<int, int> &a, const pair<int, int> &b)
    {
        return a.second < b.second;
    }

    // 贪心算法求解任务列表
    int getTaskList(Data &input, Data &output, int n)
    {
        // 添加任务
        AddTask(input);

        // 按照任务开始时间从小到大排序
        sort(tasks.begin(), tasks.end(), cmp);

        // 初始化每个工人的可用时间段
        for (int i = 0; i < n; i++)
        {
            workers.push_back(make_pair(i, 0));
        }

        // 选择能够在其开始时间之前结束并且还未被选择的工人中工作时间最早结束的那个工人来完成该任务
        for (int i = 0; i < tasks.size(); i++)
        {
            for (int j = 0; j < workers.size(); i++)
            {
                if (workers[j].second <= tasks[i].start)
                {
                    task_list.push_back(make_pair(tasks[i].id, workers[j].first));
                    workers[j].second=tasks[i].start+tasks[i].duration;
                    break;
                }
            }
            sort(workers.begin(), workers.end(), cmp_worker);
        }

        // 处理结果
        for (int i=0;i<task_list.size();i++)
        {
            auto tmp =input[task_list[i].first];
            tmp.push_back(make_pair("workerId",to_string(task_list[i].second)));
            output.emplace_back(std::move(tmp));
        }
    }
};

// 动态规划分配存储空间
#define Max_Volume 4 // 存储空间
typedef int Value;
typedef int Volume;
void GetMaxProfit()
{
    vector<pair<Volume, Value>> things{make_pair(1,15),make_pair(3,20),make_pair(4,30)};
    vector<Value> dp(Max_Volume+1,0);
    for (int i = 0; i < things.size(); i++)
    {
        for (int j = Max_Volume; j > 0; j--)
        {
            if(things[i].first <= Max_Volume)
            {
                dp[j] = max(dp[j - things[i].first] + things[i].second,dp[j]);
            }
        }
    }
}